(2/8)Projetile——发射子弹

这一章将学习如何让我们的飞船发射子弹,跟之前创建飞船一样,我们也需要给子弹新建一个精灵,创建的过程不再赘述,但是要强调一点,子弹的原点位置应当设置在头部,因为头部才是子弹本体,后面的尾焰只是画面效果。
你可以直接在图片上点击设置为原点的位置,也可以调整左上角的坐标值来设定。

在创建完子弹精灵以后我们需要创建一个子弹的对象,然后吧子弹对象跟刚刚创建的精灵关联起来即可,暂时不需要在子弹对象中写任何的事件和逻辑代码,因为我们的目的是让飞船来发射子弹,所以我们要去飞船对象中写生成子弹的代码,下面我们打开子弹对象,并在其中添加一些内容如下:

首先我们会注意到其中有两行注释,即两个“/”后的绿色文字,这些注释是不会被执行的纯文字内容,我们通常用这种方法在代码中进行一些备注,以便于我们在日后回来看代码时能更快明白这些代码的用途,只需要在任意行开头输入两个“/”即可,后面的文字内容可以任意填写。
然后我们会看到我们在之前的运动代码下方添加了一段这样的内容

if (mouse_check_button(mb_left))
{
    instance_create_layer(mouse_x,mouse_y,layer,obj_bullet)
}

这段代码的意思是

假如 (后面括号中的鼠标按钮被按下了(鼠标左键))
执行下方花括号中的命令
{
   按照后方括号中的条件创建一个对象实例(鼠标的X坐标,鼠标的Y坐标, 当前对象所在的图层,子弹对象)
}

就是说,当鼠标左键被按下时,在飞船对象所在的图层中,在鼠标指针所在的位置上,立刻生成一个子弹对象的实例。
也许有朋友不太明白实例是什么意思,你可以把我们创造的对象理解成一个一个的模版,而实例则是用这个模版做出来的直接在游戏中看到的物体,对象是相对抽象的概念,实例才是在游戏中我们真正发生交互的东西。所以当这段代码被执行以后,我们可以用子弹这一个对象,在游戏中生成无数个实例,如下图:

上述只是为了生成子弹而进行的一个小小测试,我们当然不是希望子弹跟着鼠标生成,而是希望子弹被飞船给射出去,因此它应该在飞船所在的位置生成,那我们只需要在上述代码中做一个微小的改动,即把生成位置的X、Y值进行修改,改成飞船对象自身的X、Y值即可

而且你会发现刚刚我们生成的子弹都是静止不动的,它只是生成了,但是完全不会飞,所以我们还需要给子弹增加一些运动的代码:

如上图所示,我们首先给子弹添加一个“Create”事件,这个事件跟之前飞船的“Step”事件不同,这是只在对象的实例创建的一瞬间才触发的,并且只会触发一次。
我们看到在这个Create事件中我们填入了以下代码:

direction = point_direction(x , y , mouse_x , mouse_y )
direction = direction + random_range(-4,4);
speed = 16 ;
image_angle = direction;

其中第一个“direction”是对象自带的运动方向的属性,这个方向实用的point_direction这个方法我们在上一节课控制飞船图像时曾经用过,这意味着子弹的运动朝向也是朝着我们的鼠标所在的位置的,这就能确保这个方向与飞船正面朝向一致。
在第二行还有一个第一次出现的“random_range”函数,这是用来获取随机数的,给这个函数一个数字区间参数,分别传入范围的最小值和最大值,然后这个方法就会从这个范围中随机获取一个数字作为结果给出来,这是为了模拟枪炮发射子弹时的抖动效果,为了让发射角度发生轻微的变化,使用了这个随机函数就可以使角度发生随机正负4度以内的变化。
然后我们还用内置的“speed”属性给子弹设置了一个速度,而上面那个“direction”则是自带的运动方向的属性,因此这两者结合以后就代表子弹会朝着direction所设置的方向以16的速度进行直线运动。
最后我们也要调整子弹图片本身的方向,因为之前我们已经确保运动的方向朝着鼠标,因此这里我们只需要把“image_angle"(图像角度)直接等于“direction”即可。
完成以上内容后我们就可以运行一下游戏看看效果如何了:

基本上已经如我们所想,在按下鼠标左键时,飞船会在正中央的位置生成子弹,然后生成的子弹会朝着鼠标坐在的位置飞射出去,但是我们会发现这些子弹会挡住我们的飞船,这会看起来很奇怪,我们应该都希望这些子弹从飞船下方出现,这样能确保不影响用户操作飞船的视野。
这需要运用场景编辑器中的图层,如果你没忘记上次的教学内容,应该还记得我们的飞船对象是在一个叫做“Instances”的图层上的,而刚才我们给子弹设定的生成图层就是飞船所在的图层,因此他们都在一个图层上,然后根据生成的先后顺序显示了出来,所以我们首先要做的事情是新建一个子弹的专属图层“BulletsLayer”,然后我们把这个图层放到“Instances”的下方,如下图所示:

在图层列表中,越靠下的图层就越显示在下方,在列表上方的图层会遮挡下方的图层,然后我们需要在代码中进行修改,让子弹生成到这个新的图层上:

我们把之前的layer改成了“BulletsLayer”,注意这里要用双引号,然后我们运行游戏进行测试,就会发现子弹已经被飞船盖住了:

到此为止,飞船已经能够正常发射子弹了,不过子弹的发射速度看起来稍微有点快,如果我们想要调整子弹的发射速度该怎么办呢?
我们可以定义一个新的变量——冷却时间(cooldown)
如下图,因为发射子弹的操作是由飞船进行的,因此我们首先给飞船添加一个“Create”事件,然后在其中给飞船定义一个自定义属性“cooldown”,然后默认设为0。

我们设置冷却时间的目的是,希望当这个值在0时按下鼠标左键飞船可以发出子弹,但是发出子弹以后这个值就不再是0,需要等待一段时间以后才会变成0,然后子弹再次发射,如此往复,就可以通过控制发射的时间间隔来控制子弹的发射速度了。
于是我们在发射子弹的代码中添加以下内容:

if (mouse_check_button(mb_left)) &&  (cooldown < 1)
{
    instance_create_layer(x , y ,"BulletsLayer",obj_bullet)
    cooldown = 3;
}
cooldown = cooldown - 1;

你会发现在“if”的后方条件中,我们多了一个“&&”和一个新的条件“(cooldown < 1)”。
这个"&&"代表现在需要同时满足前后两个条件,才会触发下方花括号中的命令,任何一个条件不符合都不会触发,因此冷却时间就可以控制子弹是否发射了。
而因为cooldown默认是0,永远都小于1,那如果我们不对这个冷却时间做任何的修改,那就依然会连续发射子弹,所以我们需要在发射子弹后把冷却时间修改一下,这段代码中我们把冷却时间改成了3,因此当子弹发射以后冷却时间就变成了3,3比1大,就导致子弹不会继续发射了。
但是,如果冷却时间永远都是3,那飞船在发射了第一次以后就再也发不出子弹了,所以我们要在后面再增加一个代码“cooldown = cooldown - 1”让冷却时间逐渐变小,直到小于1可以再次触发子弹的发射,就能确保子弹能连续发射但是发射的速度又是可控的了。
此时再运行游戏进行测试就会发现子弹的发射间隔已经好一些了,如果对速度依然不满意可以继续调整冷却时间的值,即发射子弹后冷却时间设置的数字,数字越大则冷却时间越长,子弹发射也就越慢。

以上就是第二课的内容,主要就是如何创建子弹,然后利用自带的运动方向和运动速度设置了子弹的移动方式,并且学习了自定义属性(变量)的方式,以及一些简单的图层位置关系,下一次会讲解如何生成敌人,以及如何销毁实例:)

2017-05-25 00:25
Comments
Write a Comment